#ifndef __BODYPACKET_H__
#define __BODYPACKET_H__

#include <map>
using namespace std;
#include "binpacket.h"
#include "key_helper.h"
#include "config.h"
using namespace CPPSocket;

struct UVHEAD;
class ProtocolObj;

class PacketParser
{
public:
	PacketParser();
	virtual ~PacketParser() {}

public:
	int pack(const ProtocolObj& po, char* buf, int& len);
	int unpack(const char* buf, int len, ProtocolObj& po);
	int unpackHead(const char* buf, UVHEAD& head);
	//int htonlu(char *buf, int size);

private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg) = 0;
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg) = 0;

protected:
	KeyHelper *helper;
};

class HeadOnlyPacketParser : public PacketParser
{
private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg){return 0;} 
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg) {return 0;}
};


class QueryCmdParser : public PacketParser
{
private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class RspdQueryCmdParser : public PacketParser
{
private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};


class QueryCountCmdParser : public PacketParser
{
private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class RspdQueryCountCmdParser : public PacketParser
{
private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class InsertCmdParser:public PacketParser
{
	private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class RspdInsertCmdParser:public PacketParser
{
	private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class DeleteCmdParser: public PacketParser
{
	private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class RspdDeleteCmdParser: public PacketParser
{
	private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class GetMsgListCmdParser:public PacketParser
{
	private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class RspdGetMsgListCmdParser:public PacketParser
{
	private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class GetNewMsgCmdParser:public PacketParser
{
	private:
	//virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg){return 0;}
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class RspdGetNewMsgCmdParser:public PacketParser
{
	private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	//virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg){return 0;}
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class RsyncCmdParser:public PacketParser
{
	private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class RspdRsyncCmdParser:public PacketParser
{
	private:
	virtual int packBody(const ProtocolObj& po, BinOutputPacket<true>& outpkg);
	virtual int unpackBody(ProtocolObj& po, BinInputPacket<true>& inpkg);
};

class PacketParserFactory
{
public:
	static PacketParser* getObj(short cmd);
	static PacketParser* insertParser(short cmd);

private:
	static map<short, PacketParser*> bpmap;
	typedef map<short, PacketParser*>::value_type valType;
};

#endif
